package demo05;

/*
 * 如果接口的实现类(或者是父类的子类)只需要使用唯一一次，那么这种情况下就可以省略对该实现类的定义，而改为使用【匿名内部类】。
 * 
 * 匿名内部类的定义格式：
 *  接口名称 对象名 = new 接口名称() {
 *      // 覆盖重写所有抽象方法
 *  };
 * 
 * 对格式“new 接口名称() {...}”进行解析：
 * 1. new代表创建对象的动作
 * 2. 接口名称代表匿名内部类需要实现哪个接口
 * 3. {...}代表匿名内部类的内容
 * 
 * 注意事项：
 * 1. 匿名内部类在【创建对象】的时候只能使用唯一一次
 *  如果希望创建多个对象，而且类的内容一样的话，那么建议使用单独定义的实现类。
 * 2. 匿名对象，在【调用方法】的时候只能使用唯一一次
 *  如果希望同一个对象调用多次方法，那么就必须给对象起名。
 * 3. 匿名内部类省略了【实现类/子类】，匿名对象省略了【对象名称】，两者不是一回事
 */
public class DemoMain {
    public static void main(String[] args) {
        // 使用匿名内部类，就不再需要定义并创建实现类对象
        MyInterface obj = new MyInterface() { // 这是匿名内部类，不是匿名对象，对象名就是obj
            @Override
            public void method1() {
                System.out.println("匿名内部类实现了方法1！");
            }

            @Override // 有多少个抽象方法就要实现多少个抽象方法，不能缺失
            public void method2() {
                System.out.println("匿名内部类实现了方法2！");
            }
        };
        obj.method1(); // 方法在匿名内部类中覆盖重写，调用后得以投入使用
        obj.method2();
        System.out.println("======================================");

        // 使用匿名内部类，并且只需要使用一次该对象，就可以省略对象名称，也就是匿名对象
        new MyInterface() { // 这既是匿名内部类，也是匿名对象
            @Override
            public void method1() {
                System.out.println("匿名内部类(匿名对象)实现了方法1！");
            }

            @Override
            public void method2() {
                System.out.println("匿名内部类(匿名对象)实现了方法2！");
            }
        }.method1(); // 匿名对象只能调用一次方法
    }
}
